﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Drawing;
using System.Windows.Media.Media3D; // PresentationCore Assemblymust be added

namespace PlanetsAndOrbs
{
    /// <summary>
    /// Base object for all geometry objects
    /// Derived classes must be able to calculate distance to intersection of ray vector,
    /// calculate new ray vector at the point of intersection,
    /// and return color or color filters
    /// </summary>
    public abstract class Object3D
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ray"></param>
        /// <param name="normal"></param>
        /// <returns></returns>
        protected double reflect(ref Vector3D ray, Vector3D normal)
        {
            double projection = Vector3D.DotProduct(normal, ray);
            ray -= normal * (2 * projection);
            ray.Normalize();
            return Math.Abs(projection);
        }

        // solves the distance equation, returns -1 if no intersection
        // returns the distance and caches what is necessary for the subsequent render
        public abstract double distance(Vector3D origin, Vector3D ray);     // used to select the next surface

        // origin is already on the surface
        // returns true if solid color without filter
        public abstract bool trace(ref Vector3D origin, ref Vector3D ray, out Vector3D filter, out Vector3D emission); 

        protected void normalizeColors(ref Vector3D c1, ref Vector3D c2)
        {
            Vector3D sum = Vector3D.Add(c1, c2);
            double norm = sum.X;
            if (norm < sum.Y)
                norm = sum.Y;
            if (norm < sum.Z)
                norm = sum.Z;
            if(norm > 1)
            {
                c1 = c1 / norm;
                c2 = c2 / norm;
            }
        }
    }
}
